package com.nantian.nfcm.bms.loan.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.nantian.nfcm.bms.loan.dao.*;
import com.nantian.nfcm.bms.loan.entity.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nantian.nfcm.bms.auth.dao.RoleInfoDao;
import com.nantian.nfcm.bms.auth.dao.UserInfoDao;
import com.nantian.nfcm.bms.auth.dao.UserRoleDao;
import com.nantian.nfcm.bms.auth.entity.RoleInfo;
import com.nantian.nfcm.bms.auth.entity.UserInfo;
import com.nantian.nfcm.bms.loan.vo.LoanBean;
import com.nantian.nfcm.util.BaseConst;
import com.nantian.nfcm.util.DateUtil;
import com.nantian.nfcm.util.ServiceException;
import com.nantian.nfcm.util.vo.LoginBean;

@Service
public class LoanApplicationService {
    private LoanApplicationDao loanApplicationDao;
    private UserInfoDao userInfoDao;
    private LoanJournalDao loanJournalDao;
    private UserRoleDao userRoleDao;
    private ApprovalPowerDao approvalPowerDao;
    private MsgInfoDao msgInfoDao;
    private RoleInfoDao roleInfoDao;
    private LoanDetailedReportDao loanDetailedReportDao;
    private LoanSubmitReportDao loanSubmitReportDao;
    private LoanAssignReportDao loanAssignReportDao;

    //这部分常量用于方法体体内判断登陆用户的角色
    private final String customerManager = "客户经理";
    private final String submiter = "贷款上报人";
    private final String examiner = "独立审查人";
    private final String assigner = "贷款审查分配人";

    @Autowired
    public LoanApplicationService(LoanApplicationDao loanApplicationDao, UserInfoDao userInfoDao, LoanJournalDao loanJournalDao,
                                  UserRoleDao userRoleDao, ApprovalPowerDao approvalPowerDao, MsgInfoDao msgInfoDao,
                                  RoleInfoDao roleInfoDao, LoanDetailedReportDao loanDetailedReportDao,LoanSubmitReportDao loanSubmitReportDao,
                                  LoanAssignReportDao loanAssignReportDao) {

        this.loanApplicationDao = loanApplicationDao;
        this.userInfoDao = userInfoDao;
        this.loanJournalDao = loanJournalDao;
        this.userRoleDao = userRoleDao;
        this.approvalPowerDao = approvalPowerDao;
        this.msgInfoDao = msgInfoDao;
        this.roleInfoDao = roleInfoDao;
        this.loanDetailedReportDao = loanDetailedReportDao;
        this.loanSubmitReportDao = loanSubmitReportDao;
        this.loanAssignReportDao = loanAssignReportDao;
    }


    /**
     * 新增贷款信息
     *
     * @param loanBean  贷款信息VO
     * @param loginUser 登陆用户ID
     * @return LoanBean
     * @throws ServiceException 返回异常
     */
    @Transactional
    public LoanBean addLoanApplication(LoanBean loanBean, LoginBean loginUser) throws ServiceException {
        LoanInfo loanInfo = loanBean.getLoanInfo();

        ObjectMapper mapper = new ObjectMapper();

        String detail;

        try {
            detail = mapper.writeValueAsString(loanInfo);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            throw new ServiceException("贷款申请详情信息数据格式出错");
        }
        LoanApplication perLoanApp = vo2po(loanBean);

        //设置贷款ID
        String loanId = "L" + DateUtil.getCurrentTime("yyMMddHHmmss");
        perLoanApp.setLoanId(loanId);

        //设置当前回执为空
        perLoanApp.setCurProcessFeedback("-");
        //设置当前进度处理人为空
        perLoanApp.setCurProcessHandler("-");
        //设置当前进度状态
        perLoanApp.setProcessStat(LoanStat.WAIT.getValue());

        String nowDate = DateUtil.getCurrentTime("yyyy-MM-dd");
        //设置贷款信息提交到系统的时间
        perLoanApp.setInitTime(nowDate);
        //设置流程最近更新时间
        perLoanApp.setCurProcessUpdateTime(nowDate);
        //设置贷款人姓名
        perLoanApp.setBorrowerName(loanInfo.getBorrowerName());
        //设置贷款接件时间
        perLoanApp.setPickupTime(loanBean.getPickupTime());
        //设置分配人为空
        perLoanApp.setAssigner("-");
        //设置上报人为空
        perLoanApp.setSubmiteHandler("-");
        //设置独立审查人为空
        perLoanApp.setApprovalHandler("-");
        //设置业务类型
        perLoanApp.setLoanType(loanInfo.getBusinessTypes());

        //设置贷款明细数据
        perLoanApp.setDetail(detail);

        //设置贷款的子类型
        perLoanApp.setLoanSubType(loanBean.getLoanSubType());

        LoanApplication loanApplicationRet = loanApplicationDao.save(perLoanApp);
        LoanBean loanBeanRet = po2vo(loanApplicationRet);

        //记录流水信息
        saveJournal(perLoanApp, loginUser.getUserName(), "提交了贷款申请");


        // *************开始记录通知消息******************
        //查询上报人的角色ID
        List<RoleInfo> roleIds = roleInfoDao.findByRoleName(this.submiter);

        //获取所有上报人用户
        List<UserInfo> submiterList = userRoleDao.findUserInfoByRoleId(roleIds.get(0).getRoleId());

        //生成所有人的通知消息
        List<MsgInfo> msgInfoList = new ArrayList<>();
        for (UserInfo userInfo : submiterList) {
            MsgInfo msgInfo = new MsgInfo();
            msgInfo.setLoanId(loanId);
            msgInfo.setMsg(perLoanApp.getBorrowerName() + "的贷款申请"  + perLoanApp.getLoanId() + "需要上报");
            msgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            msgInfo.setUserName(userInfo.getUserName());
            msgInfoList.add(msgInfo);
        }

        //保存记录
        if (msgInfoList.size() > 0) {
            msgInfoDao.save(msgInfoList);
        }

        //TODO 新增贷款记录时同步新增贷款报表记录
        LoanDetailedReport loanDetailedReport = new LoanDetailedReport();
        loanDetailedReport = loanApp2Report(perLoanApp, loanDetailedReport);
        loanDetailedReport.setApprovalTime("");
        loanDetailedReportDao.save(loanDetailedReport);
        return loanBeanRet;
    }


    /**
     * 标记分配人已经收到贷款纸质资料
     * @param loanBean
     */
    @Transactional
    public void assignerReceivedFiles(LoanBean loanBean, LoginBean loginUser) throws ServiceException {
        //获取需要标记的贷款ID
        List<String> ids = loanBean.getIds();
        if (ids == null || ids.size() == 0) {
            throw new ServiceException("贷款转交上送的ID为空");
        }
        
        //执行标记
        for (String loanId : ids) {
            LoanApplication loanApplication = loanApplicationDao.findOne(loanId);

            loanApplication.setProcessStat(LoanStat.RECEIVED_FILES.getValue());
            
            loanApplicationDao.save(loanApplication);

            saveJournal(loanApplication, loginUser.getUserName(), "收到了贷款纸质资料，准备分配独立审查人");

            // ************开始记录通知消息**************

            //生成转交通知消息
            MsgInfo msgInfo = new MsgInfo();
            msgInfo.setLoanId(loanApplication.getLoanId());
            msgInfo.setMsg("分配人已收到贷款" + loanApplication.getLoanId() + "的纸质资料");
            msgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            msgInfo.setUserName(loanApplication.getOperator());
            msgInfoDao.save(msgInfo);

        }
    }
    
    /**
     * 工作转交
     *
     * @param loanBean  loanBean
     * @param loginUser loginUser
     * @throws ServiceException ServiceException
     */
    @Transactional
    public void workTransfer(LoanBean loanBean, LoginBean loginUser) throws ServiceException {
        //获取需要转移工作的贷款ID
        List<String> ids = loanBean.getIds();
        if (ids == null || ids.size() == 0) {
            throw new ServiceException("贷款转交上送的ID为空");
        }

        //检查当前人员是否为客户经理或独立贷款审查人
        List<RoleInfo> roleInfos = userRoleDao.findRoleInfoByUserName(loginUser.getUserName());

        //查询当前登陆人员的角色名称
        String currentRoleName = "";
        out:
        for (RoleInfo roleInfo : roleInfos) {
            switch (roleInfo.getRoleName()) {
                case customerManager:
                case examiner:
                    currentRoleName = roleInfo.getRoleName();
                    break out;
                default:
                    //如果当前登陆人员不是客户经理或独立贷款审查人则退出功能
                    throw new ServiceException(roleInfo.getRoleName() + "不能执行贷款分配操作");
            }
        }

        //执行转交
        for (String loanId : ids) {
            LoanApplication loanApplication = loanApplicationDao.findOne(loanId);

            String workTransfer;

            //如果登陆用户是客户经理，那么工作转交就是客户经理之间的转交
            if (currentRoleName.equals(customerManager)) {
                loanApplication.setOperator(loanBean.getOperator());
                workTransfer = loanBean.getOperator();
            } else {
                //如果登陆用户是独立贷款审查人，那么工作转交就是独立贷款审查人之间的转交
                loanApplication.setApprovalHandler(loanBean.getApprovalHandler());
                workTransfer = loanBean.getApprovalHandler();
            }

            LoanApplication loanAppRet = loanApplicationDao.save(loanApplication);

            //查询被转交人的用户信息
            UserInfo workTransferUserInfo = userInfoDao.findOne(workTransfer);

            saveJournal(loanApplication, loginUser.getUserName(), "将工作转交给了" + workTransferUserInfo.getRealName());

            // ************开始记录通知消息**************

            //生成转交通知消息
            MsgInfo msgInfo = new MsgInfo();
            msgInfo.setLoanId(loanApplication.getLoanId());
            msgInfo.setMsg(loginUser.getRealName() + "将贷款" + loanApplication.getLoanId() + "转交给您处理");
            msgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            msgInfo.setUserName(workTransferUserInfo.getUserName());
            msgInfoDao.save(msgInfo);

            //TODO 修改贷款报表记录
            List<LoanDetailedReport> reports = loanDetailedReportDao.findAllByLoanId(loanId);
            if (reports != null && reports.size() == 1) {
                LoanDetailedReport loanDetailedReport = reports.get(0);
                loanDetailedReport = loanApp2Report(loanAppRet, loanDetailedReport);
                loanDetailedReportDao.save(loanDetailedReport);
            } else {
                throw new ServiceException("报表流水出现脏数据");
            }
        }

    }

    /**
     * 更新贷款信息
     *
     * @param loanBean  贷款信息VO
     * @param loginUser 登陆用户ID
     * @return LoanBean LoanBean
     * @throws ServiceException ServiceException
     */
    @Transactional
    public LoanBean updateLoanApplication(LoanBean loanBean, LoginBean loginUser) throws ServiceException {
        String loanId = loanBean.getLoanId();
        LoanApplication loanApplication = loanApplicationDao.findOne(loanId);
        if (loanApplication == null) {
            throw new ServiceException("贷款申请信息不存在");
        }

        if (loanApplication.getProcessStat().equals(LoanStat.EXAMINE_FAIL.getValue())) {
            throw new ServiceException("贷款已被退件无法编辑！");
        }

        if (loanApplication.getProcessStat().equals(LoanStat.APPROVAL_FAIL_GEJING.getValue()) ||
                loanApplication.getProcessStat().equals(LoanStat.APPROVAL_FAIL_LIANSHE.getValue())) {
            throw new ServiceException("该贷款已经完成审批，且审批失败，不能再编辑！");
        }

        if (loanApplication.getProcessStat().equals(LoanStat.APPROVAL_SUCC_GEJING.getValue()) ||
                loanApplication.getProcessStat().equals(LoanStat.APPROVAL_SUCC_LIANSHE.getValue())) {
            throw new ServiceException("该贷款已经完成审批，不能再编辑！");
        }

        LoanInfo loanInfo = loanBean.getLoanInfo();
        ObjectMapper mapper = new ObjectMapper();
        try {
            loanApplication.setDetail(mapper.writeValueAsString(loanInfo));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            throw new ServiceException("贷款申请详细信息数据格式错误");
        }

        //设置当前回执
        if (loanApplication.getCurProcessFeedback() == null ||
                loanApplication.getCurProcessFeedback().equals("")) {
            loanApplication.setCurProcessFeedback("-");
        }

        //设置当前进度处理人
        if (loanApplication.getCurProcessHandler() == null ||
                loanApplication.getCurProcessHandler().equals("")) {
            loanApplication.setCurProcessHandler("-");
        }

        //设置当前进度状态
        if (loanApplication.getProcessStat() == null ||
                loanApplication.getProcessStat().equals("")) {
            loanApplication.setProcessStat(LoanStat.WAIT.cnStr());
        }

        String nowDate = DateUtil.getCurrentTime("yyyy-MM-dd");
        //设置流程最近更新时间
        loanApplication.setCurProcessUpdateTime(nowDate);
        //设置审查人员
        if (loanApplication.getProcessStat() == null ||
                loanApplication.getAssigner().equals("")) {
            loanApplication.setAssigner("-");
        }

        //设置进件处理人员
        if (loanApplication.getSubmiteHandler() == null ||
                loanApplication.getSubmiteHandler().equals("")) {
            loanApplication.setSubmiteHandler("-");
        }

        //设置审批人员
        if (loanApplication.getApprovalHandler() == null ||
                loanApplication.getApprovalHandler().equals("")) {
            loanApplication.setApprovalHandler("-");
        }

        LoanApplication loanAppRet = loanApplicationDao.save(loanApplication);

        saveJournal(loanApplication, loginUser.getUserName(), "修改了贷款信息");

        List<LoanDetailedReport> reports = loanDetailedReportDao.findAllByLoanId(loanId);
        if (reports != null && reports.size() == 1) {
            LoanDetailedReport loanDetailedReport = reports.get(0);
            loanDetailedReportDao.save(loanApp2Report(loanAppRet, loanDetailedReport));
        } else {
            throw new ServiceException("报表流水出现脏数据");
        }
        return loanBean;
    }

    /**
     * 上报贷款，方法加了同步，上报出现并发
     *
     * @param loanlBean loanlBean
     * @throws ServiceException ServiceException
     */
    @Transactional
    public synchronized void loanSubmit(LoanBean loanlBean, LoginBean loginUser) throws ServiceException {
        List<String> ids = loanlBean.getIds();
        if (ids == null || ids.size() == 0) {
            throw new ServiceException("贷款上报上送的ID为空");
        }

        //查询贷款身材分配人的角色ID
        List<RoleInfo> roleIds = roleInfoDao.findByRoleName(this.assigner);
        //获取所有贷款审查分配人用户
        List<UserInfo> assignerList = userRoleDao.findUserInfoByRoleId(roleIds.get(0).getRoleId());

        for (String id : ids) {
            //根据ID查询贷款流程流水信息，将分配的标志置为1
            LoanApplication loanApp = loanApplicationDao.findOne(id);

            //如果贷款此前状态为等待上报状态
            if (!loanApp.getProcessStat().equals(LoanStat.WAIT.getValue())) {
                throw new ServiceException("只有处于“等待上报状态”的贷款才能上报，您选中的记录中" + loanApp.getLoanId() + "状态不正确！");
            }

            //如果这条贷款已经被上报过那么跳过该记录的更新，这种情况只有在并发时才会出现
            if (loanApp.getSubmiteHandler() != null && !loanApp.getSubmiteHandler().equals("-") && !loanApp.getSubmiteHandler().equals("")) {
                continue;
            }

            loanApp.setProcessStat(LoanStat.SUBMIT.getValue());
            loanApp.setCurProcessHandler(loginUser.getUserName());
            loanApp.setCurProcessUpdateTime(DateUtil.getCurrentTime("yyyy-MM-dd"));
            loanApp.setSubmiteHandler(loginUser.getUserName());
            loanApp.setAssigner(loanlBean.getAssigner());
            LoanApplication loanAppRet = loanApplicationDao.save(loanApp);

            saveJournal(loanApp, loginUser.getUserName(), "已经收到贷款纸质资料，并向区联社上报");

            // ************开始记录通知消息**************
            //生成所有人的通知消息
            List<MsgInfo> msgInfoList = new ArrayList<>();
            for (UserInfo userInfo : assignerList) {
                MsgInfo msgInfo = new MsgInfo();
                msgInfo.setLoanId(loanApp.getLoanId());
                msgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请"  + loanApp.getLoanId() + "等待分配独立审查人");
                msgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
                msgInfo.setUserName(userInfo.getUserName());
                msgInfoList.add(msgInfo);
            }

            //保存记录
            if (msgInfoList.size() > 0) {
                msgInfoDao.save(msgInfoList);
            }


            //生成对客户经理的消息
            MsgInfo customerManagerMsgInfo = new MsgInfo();
            customerManagerMsgInfo.setLoanId(loanApp.getLoanId());
            customerManagerMsgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请"  + loanApp.getLoanId() + "已上报");
            customerManagerMsgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            customerManagerMsgInfo.setUserName(loanApp.getOperator());
            msgInfoDao.save(customerManagerMsgInfo);

            //贷款报表流水中更新上报时间
            List<LoanDetailedReport> reports = loanDetailedReportDao.findAllByLoanId(id);
            if (reports != null && reports.size() == 1) {
                LoanDetailedReport loanDetailedReport = reports.get(0);
                loanDetailedReport.setApprovalTime("");
                loanDetailedReportDao.save(loanApp2Report(loanAppRet, loanDetailedReport));
            } else {
                throw new ServiceException("报表流水出现脏数据");
            }

            //记录上报贷款打印清单
            LoanSubmitReport loanSubmitReport = loanApp2SubmitReport(loanAppRet);
            loanSubmitReportDao.save(loanSubmitReport);
        }
    }

    /**
     * 将贷款返回给分配人
     *
     * @param loanlBean loanlBean
     * @param loginUser loginUser
     * @throws ServiceException ServiceException
     */
    @Transactional
    public void backToAssigner(LoanBean loanlBean, LoginBean loginUser) throws ServiceException {
        List<String> ids = loanlBean.getIds();
        if (ids == null || ids.size() == 0) {
            throw new ServiceException("分配贷款独立审查人上报的ID为空");
        }


        //对上送的贷款记录进行独立审查人分配
        for (String id : ids) {
            //查询贷款对应的贷款分配人
            //UserInfo assignerUser = userInfoDao.findOne(loanlBean.getAssigner());

            //查询需要审查的记录
            LoanApplication loanApp = loanApplicationDao.findOne(id);

            UserInfo assignerUser = userInfoDao.findOne(loanApp.getAssigner());

            //设置贷款状态为等待分配状态
            loanApp.setCurProcessHandler(loanApp.getAssigner());
            loanApp.setApprovalHandler("-");
            loanApp.setProcessStat(LoanStat.RECEIVED_FILES.getValue());
            LoanApplication loanAppRet = loanApplicationDao.save(loanApp);

            saveJournal(loanApp, loginUser.getUserName(), "向分配人" + assignerUser.getRealName() + "申请重新分配审查工作");

            // ************开始记录通知消息**************/

            //生成分配通知消息
            MsgInfo msgInfo = new MsgInfo();
            msgInfo.setLoanId(loanApp.getLoanId());
            msgInfo.setMsg(loginUser.getRealName() + "向您申请重新分配贷款" + loanApp.getLoanId() + "的独立审查人");
            msgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            msgInfo.setUserName(assignerUser.getUserName());
            msgInfoDao.save(msgInfo);

            //生成对客户经理的消息
            MsgInfo customerManagerMsgInfo = new MsgInfo();
            customerManagerMsgInfo.setLoanId(loanApp.getLoanId());
            customerManagerMsgInfo.setMsg("由于独立审查人繁忙，贷款" + loanApp.getLoanId() + "需要重新分配");
            customerManagerMsgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            customerManagerMsgInfo.setUserName(loanApp.getOperator());
            msgInfoDao.save(customerManagerMsgInfo);

            //TODO 贷款报表流水审查人信息置为null
            List<LoanDetailedReport> reports = loanDetailedReportDao.findAllByLoanId(id);
            if (reports != null && reports.size() == 1) {
                LoanDetailedReport loanDetailedReport = reports.get(0);
                loanDetailedReportDao.save(loanApp2Report(loanAppRet, loanDetailedReport));
            } else {
                throw new ServiceException("报表流水出现脏数据");
            }
        }
    }

    /**
     * 分配贷款独立审查人，以防出现并发加了同步锁
     *
     * @param loanlBean loanlBean
     * @param loginUser loginUser
     */
    @Transactional
    public synchronized void loanAssigned(LoanBean loanlBean, LoginBean loginUser) throws ServiceException {

        List<String> ids = loanlBean.getIds();
        if (ids == null || ids.size() == 0) {
            throw new ServiceException("分配贷款独立审查人上报的ID为空");
        }

        //查询分配的独立审查人用户信息
        UserInfo approvalUser = userInfoDao.findOne(loanlBean.getApprovalHandler());

        //对上送的贷款记录进行独立审查人分配
        for (String id : ids) {
            //查询需要审查的记录
            LoanApplication loanApp = loanApplicationDao.findOne(id);

            //如果查找不到记录
            if (loanApp == null) {
                throw new ServiceException("未找到贷款记录" + id);
            }

            if (!loanApp.getProcessStat().equals(LoanStat.RECEIVED_FILES.getValue())) {
                throw new ServiceException("您还没有确认贷款" + loanApp.getLoanId() + "已收到纸质资料，不能执行分配操作！");
            }

            //如果贷款已经被分配了独立审查人则跳过更新,这种情况只会在并发的时候出现
            if (loanApp.getApprovalHandler() != null && !loanApp.getApprovalHandler().equals("-") && !loanApp.getApprovalHandler().equals("")) {
                continue;
            }

            //设置独立审查人
            loanApp.setCurProcessHandler(loanlBean.getApprovalHandler());
            loanApp.setApprovalHandler(loanlBean.getApprovalHandler());
            loanApp.setProcessStat(LoanStat.ASSIGNED.getValue());
            //设置分配人
            loanApp.setAssigner(loginUser.getUserName());
            LoanApplication loanAppRet = loanApplicationDao.save(loanApp);

            saveJournal(loanApp, loginUser.getUserName(), "已经收到个金上报的贷款纸质资料，并将贷款分配给" + approvalUser.getRealName() + "审查");

            // ************开始记录通知消息**************/

            //生成分配通知消息
            MsgInfo msgInfo = new MsgInfo();
            msgInfo.setLoanId(loanApp.getLoanId());
            msgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请"  + loanApp.getLoanId() + "需要您审查");
            msgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            msgInfo.setUserName(approvalUser.getUserName());
            msgInfoDao.save(msgInfo);

            //生成对客户经理的消息
            MsgInfo customerManagerMsgInfo = new MsgInfo();
            customerManagerMsgInfo.setLoanId(loanApp.getLoanId());
            customerManagerMsgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请"  + loanApp.getLoanId() + "进入到审查阶段");
            customerManagerMsgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            customerManagerMsgInfo.setUserName(loanApp.getOperator());
            msgInfoDao.save(customerManagerMsgInfo);

            //TODO 贷款报表流水更新审查人信息
            List<LoanDetailedReport> reports = loanDetailedReportDao.findAllByLoanId(id);
            if (reports != null && reports.size() == 1) {
                LoanDetailedReport loanDetailedReport = reports.get(0);
                loanDetailedReportDao.save(loanApp2Report(loanAppRet, loanDetailedReport));
            } else {
                throw new ServiceException("报表流水出现脏数据");
            }
        }

    }

    /**
     * 审查成功
     *
     * @param loanBean loanBean
     * @throws ServiceException ServiceException
     */
    @Transactional
    public void loanReviewSuccess(LoanBean loanBean, LoginBean loginUser) throws ServiceException {
        String id = loanBean.getLoanId();
        //查询需要审查的记录
        LoanApplication loanApp = loanApplicationDao.findOne(id);

        //获取详情字段
        LoanInfo loanInfo = loanBean.getLoanInfo();

        List<ApprovalPower> approvalPower;
        String loanType = loanApp.getLoanType();
        String loanSubType = loanApp.getLoanSubType();
        if (loanSubType == null || loanSubType.equals("")) {
            approvalPower = approvalPowerDao.findByParam(loanType, loanInfo.getGuaranteeMethod());
        } else {
            approvalPower = approvalPowerDao.findByParam(loanType, loanSubType, loanInfo.getGuaranteeMethod());
        }


        if (approvalPower.size() != 1) {
            throw new ServiceException("数据库个金部审批权限记录不存在或存在脏数据，无法提交审批");
        }

        //获取个金部贷款审批权限
        int loanApprovalAmount = approvalPower.get(0).getLoanAmount();

        String remark = "";

        if (Integer.parseInt(loanInfo.getAmount()) > loanApprovalAmount) {
            //大于权限贷款记录设置为区联社审批
            loanApp.setProcessStat(LoanStat.EXAMINE_SUCC_LIANSHE.getValue());
            remark += "审查贷款完毕，贷款金额大于" + loanApprovalAmount + "万元，提交区联社审批";
        } else {
            //小于权限贷款记录设置为区联社审批
            loanApp.setProcessStat(LoanStat.EXAMINE_SUCC_GEJING.getValue());
            remark += "审查贷款完毕，贷款金额小于" + loanApprovalAmount + "万元，提交个金部经理审批";
        }

        loanApp.setCurProcessUpdateTime(DateUtil.getCurrentTime("yyyy-MM-dd"));
        loanApp.setCurProcessHandler(loginUser.getUserName());
        loanApp.setAssigner(loginUser.getUserName());
        loanApp.setCurProcessFeedback(loanBean.getCurProcessFeedback());

        String detail;
        try {
            ObjectMapper mapper = new ObjectMapper();
            detail = mapper.writeValueAsString(loanInfo);
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }
        loanApp.setDetail(detail);
        LoanApplication loanAppRet = loanApplicationDao.save(loanApp);

        saveJournal(loanApp, loginUser.getUserName(), remark);


        // ************开始记录通知消息**************/

        //生成审查成功通知消息
        MsgInfo msgInfo = new MsgInfo();
        msgInfo.setLoanId(loanApp.getLoanId());
        msgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请"  + loanApp.getLoanId() + "已完成审查，请您关注审批结果");
        msgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));

        //根据个金权限不同，设置需要通知的角色
        if (Integer.parseInt(loanInfo.getAmount()) > loanApprovalAmount) {
            msgInfo.setUserName(loanApp.getAssigner());
        } else {
            msgInfo.setUserName(loanApp.getSubmiteHandler());
        }

        msgInfoDao.save(msgInfo);


        //生成对客户经理的消息
        MsgInfo customerManagerMsgInfo = new MsgInfo();
        customerManagerMsgInfo.setLoanId(loanApp.getLoanId());
        customerManagerMsgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请"  + loanApp.getLoanId() + "进入审批阶段");
        customerManagerMsgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
        customerManagerMsgInfo.setUserName(loanApp.getOperator());
        msgInfoDao.save(customerManagerMsgInfo);

        //TODO 贷款报表流水更新审查信息
        List<LoanDetailedReport> reports = loanDetailedReportDao.findAllByLoanId(id);
        if (reports != null && reports.size() == 1) {
            LoanDetailedReport loanDetailedReport = reports.get(0);
            loanDetailedReportDao.save(loanApp2Report(loanAppRet, loanDetailedReport));
        } else {
            throw new ServiceException("报表流水出现脏数据");
        }

        //生成回交贷款清单
        LoanAssignReport loanAssignReport = loanApp2AssignReport(loanAppRet);
        loanAssignReportDao.save(loanAssignReport);
    }

    /**
     * 要求补件
     *
     * @param loanBean loanBean
     * @throws ServiceException ServiceException
     */
    @Transactional
    public void updateLoanJournalResubmit(LoanBean loanBean, LoginBean loginUser) throws ServiceException {
        String id = loanBean.getLoanId();
        LoanApplication loanApp = loanApplicationDao.findOne(id);

        //如果上一个阶段是已分配独立审查人等待审查阶段,那么标记为审查失败需要补件
        if (loanApp.getProcessStat().equals(LoanStat.ASSIGNED.getValue())) {
            loanApp.setProcessStat(LoanStat.EXAMINE_UPDATE.getValue());
            loanApp.setCurProcessHandler(loginUser.getUserName());

            loanApp.setCurProcessFeedback(loanBean.getCurProcessFeedback());

            loanApp.setCurProcessUpdateTime(DateUtil.getCurrentTime("yyyy-MM-dd"));

            //更新详情字段（补件内容包含在详情字段中）
            String detail;
            try {
                ObjectMapper mapper = new ObjectMapper();
                detail = mapper.writeValueAsString(loanBean.getLoanInfo());
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                throw new ServiceException("贷款申请详情信息数据格式出错");
            }

            loanApp.setDetail(detail);
            LoanApplication loanAppRet = loanApplicationDao.save(loanApp);

            saveJournal(loanApp, loginUser.getUserName(), "发现贷款缺少资料，要求补件");

            //************开始记录通知消息**************/

            //生成补件通知消息
            MsgInfo msgInfo = new MsgInfo();
            msgInfo.setLoanId(loanApp.getLoanId());
            msgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请"  + loanApp.getLoanId() + "需要补件，请尽快处理");
            msgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            msgInfo.setUserName(loanApp.getOperator());

            msgInfoDao.save(msgInfo);

            List<LoanDetailedReport> reports = loanDetailedReportDao.findAllByLoanId(id);
            if (reports != null && reports.size() == 1) {
                LoanDetailedReport loanDetailedReport = reports.get(0);
                loanDetailedReportDao.save(loanApp2Report(loanAppRet, loanDetailedReport));
            } else {
                throw new ServiceException("报表流水出现脏数据");
            }
            //生成回交贷款清单
            LoanAssignReport loanAssignReport = loanApp2AssignReport(loanAppRet);
            loanAssignReportDao.save(loanAssignReport);
        } else {
            throw new ServiceException("只有处于“已分配独立审查人等待审查”阶段的贷款才能要求补件");
        }
    }

    /**
     * 补件完成
     *
     * @param loanBean loanBean
     * @throws ServiceException ServiceException
     */
    @Transactional
    public void loanResubmitComplete(LoanBean loanBean, LoginBean loginUser) throws ServiceException {

        //检查当前人员是否为客户经理
        List<RoleInfo> roleInfos = userRoleDao.findRoleInfoByUserName(loginUser.getUserName());

        out:
        for (RoleInfo roleInfo : roleInfos) {
            switch (roleInfo.getRoleName()) {
                case customerManager:
                    break out;
                default:
                    throw new ServiceException(roleInfo.getRoleName() + "不能执行补件操作");
            }
        }

        String id = loanBean.getLoanId();
        LoanApplication loanApp = loanApplicationDao.findOne(id);

        //如果上一个阶段是要求补件
        if (loanApp.getProcessStat().equals(LoanStat.EXAMINE_UPDATE.getValue())) {


            loanApp.setProcessStat(LoanStat.ASSIGNED.getValue());
            loanApp.setCurProcessHandler(loginUser.getUserName());
            loanApp.setCurProcessUpdateTime(DateUtil.getCurrentTime("yyyy-MM-dd"));

            //设置detail
            String detail;
            ObjectMapper mapper = new ObjectMapper();
            try {
                detail = mapper.writeValueAsString(loanBean.getLoanInfo());
            } catch (JsonProcessingException e) {
                e.printStackTrace();
                throw new ServiceException("贷款申请详情信息数据格式出错");
            }
            loanApp.setDetail(detail);
            LoanApplication loanAppRet = loanApplicationDao.save(loanApp);

            saveJournal(loanApp, loginUser.getUserName(), "已按要求对贷款进行补件，等待重新审查");

            //************开始记录通知消息**************/

            //生成补件通知消息
            MsgInfo msgInfo = new MsgInfo();
            msgInfo.setLoanId(loanApp.getLoanId());
            msgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请"  + loanApp.getLoanId() + "已完成补件，请您尽快审查");
            msgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            msgInfo.setUserName(loanApp.getApprovalHandler());

            msgInfoDao.save(msgInfo);

            //TODO 补件时修改贷款报表记录
            List<LoanDetailedReport> reports = loanDetailedReportDao.findAllByLoanId(id);
            if (reports != null && reports.size() == 1) {
                LoanDetailedReport loanDetailedReport = reports.get(0);
                loanDetailedReportDao.save(loanApp2Report(loanAppRet, loanDetailedReport));
            } else {
                throw new ServiceException("报表流水出现脏数据");
            }
        } else {
            throw new ServiceException("只有处于“审查失败，需要补件”阶段的贷款才能执行补件");
        }

    }

    /**
     * 直接上报区联社
     *
     * @param loanBean  loanBean
     * @param loginUser loginUser
     */
    public void reportToParent(LoanBean loanBean, LoginBean loginUser) throws ServiceException{


        ArrayList<String> ids = loanBean.getIds();

        for (String id : ids) {
            //查询对应记录
            LoanApplication loanApp = loanApplicationDao.findOne(id);

            loanApp.setProcessStat(LoanStat.CAN_NOT_EXAMINE.getValue());
            loanApp.setCurProcessHandler(loginUser.getUserName());

            loanApp.setCurProcessUpdateTime(DateUtil.getCurrentTime("yyyy-MM-dd"));
            LoanApplication loanAppRet = loanApplicationDao.save(loanApp);

            saveJournal(loanApp, loginUser.getUserName(), "将一笔贷款直接上报区联社审批");

            // ************开始记录通知消息**************/

            //生成审查成功通知消息
            MsgInfo msgInfo = new MsgInfo();
            msgInfo.setLoanId(loanApp.getLoanId());
            msgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请"  + loanApp.getLoanId() + "被直接上报区联社审批，请关注审批结果");
            msgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));

            //通知贷款审查分配人注意跟进
            msgInfo.setUserName(loanApp.getAssigner());

            msgInfoDao.save(msgInfo);

            //生成对客户经理的消息
            MsgInfo customerManagerMsgInfo = new MsgInfo();
            customerManagerMsgInfo.setLoanId(loanApp.getLoanId());
            customerManagerMsgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请"  + loanApp.getLoanId() + "被直接上报区联社审批");
            customerManagerMsgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            customerManagerMsgInfo.setUserName(loanApp.getOperator());
            msgInfoDao.save(customerManagerMsgInfo);

            List<LoanDetailedReport> reports = loanDetailedReportDao.findAllByLoanId(id);
            if (reports != null && reports.size() == 1) {
                LoanDetailedReport loanDetailedReport = reports.get(0);
                loanDetailedReportDao.save(loanApp2Report(loanAppRet, loanDetailedReport));
            } else {
                throw new ServiceException("报表流水出现脏数据");
            }
        }
    }

    /**
     * 要求退件
     *
     * @param loanBean loanBean
     * @throws ServiceException ServiceException
     */
    @Transactional
    public void updateLoanJournalRefuse(LoanBean loanBean, LoginBean loginUser) throws ServiceException {
        String id = loanBean.getLoanId();

        //查询对应记录
        LoanApplication loanApp = loanApplicationDao.findOne(id);

        //如果上一个阶段是已分配独立审查人等待审查阶段,那么标记为审查失败需要推荐
        if (loanApp.getProcessStat().equals(LoanStat.ASSIGNED.getValue())) {

            loanApp.setProcessStat(LoanStat.EXAMINE_FAIL.getValue());

            loanApp.setCurProcessHandler(loginUser.getUserName());
            loanApp.setCurProcessFeedback(loanBean.getCurProcessFeedback());

            loanApp.setCurProcessUpdateTime(DateUtil.getCurrentTime("yyyy-MM-dd"));

            loanApp.setApprovalHandler(loginUser.getUserName());
            LoanApplication loanAppRet = loanApplicationDao.save(loanApp);

            saveJournal(loanApp, loginUser.getUserName(), "审查贷款不通过，对贷款执行了退件");

            //************开始记录通知消息**************/

            //生成退件通知消息
            MsgInfo msgInfo = new MsgInfo();
            msgInfo.setLoanId(loanApp.getLoanId());
            msgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请"  + loanApp.getLoanId() + "被退件了");
            msgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            msgInfo.setUserName(loanApp.getOperator());

            msgInfoDao.save(msgInfo);

            //新增修改为update
            List<LoanDetailedReport> reports = loanDetailedReportDao.findAllByLoanId(id);
            if (reports != null && reports.size() == 1) {
                LoanDetailedReport loanDetailedReport = reports.get(0);
                loanDetailedReportDao.save(loanApp2Report(loanAppRet, loanDetailedReport));
            } else {
                throw new ServiceException("报表流水出现脏数据");
            }

            //生成回交贷款清单
            LoanAssignReport loanAssignReport = loanApp2AssignReport(loanAppRet);
            loanAssignReportDao.save(loanAssignReport);
        } else {
            throw new ServiceException("只有处于“已分配独立审查人等待审查”阶段的贷款才能退件");
        }

    }

    /**
     * 记录审批结果
     *
     * @param loanBean       vo
     * @param loginUser      登陆用户ID
     * @param approvalResult 审批结果
     * @throws ServiceException ServiceException
     */
    @Transactional
    public void updateLoanJournal2Review(LoanBean loanBean, LoginBean loginUser, boolean approvalResult) throws ServiceException {

        ArrayList<String> ids = loanBean.getIds();

        String userRoleStr = "";

        //检查当前人员是否贷款上报人或审查分配人
        List<RoleInfo> roleInfos = userRoleDao.findRoleInfoByUserName(loginUser.getUserName());
        out:
        for (RoleInfo roleInfo : roleInfos) {
            switch (roleInfo.getRoleName()) {
                case submiter:
                case assigner:
                    userRoleStr = roleInfo.getRoleName();
                    break out;
                default:
                    throw new ServiceException(roleInfo.getRoleName() + "不能记录贷款审批结果");
            }
        }

        //循环设置个金部经理贷款审批
        for (String id : ids) {
            LoanApplication loanApp = loanApplicationDao.findOne(id);


            String remark = "";
            //如果贷款为等待个金经理审批
            if (loanApp.getProcessStat().equals(LoanStat.EXAMINE_SUCC_GEJING.getValue())) {
                if (userRoleStr.equals(submiter)) {

                    if (approvalResult) {
                        loanApp.setProcessStat(LoanStat.APPROVAL_SUCC_GEJING.getValue());
                        remark = "已确认个金部经理审批贷款成功";
                    } else {
                        loanApp.setProcessStat(LoanStat.APPROVAL_FAIL_GEJING.getValue());
                        remark = "已确认个金部经理贷款审批未通过";
                    }

                } else {
                    throw new ServiceException("只有“贷款上报人”可以记录个金部审批贷款的结果");
                }
            }

            //如果贷款为等待区联社审批，或个经部无权需要区联社直接审批
            if (loanApp.getProcessStat().equals(LoanStat.EXAMINE_SUCC_LIANSHE.getValue()) ||
                    loanApp.getProcessStat().equals(LoanStat.CAN_NOT_EXAMINE.getValue())) {
                if (userRoleStr.equals(assigner)) {
                    if (approvalResult) {
                        loanApp.setProcessStat(LoanStat.APPROVAL_SUCC_LIANSHE.getValue());
                        remark = "已确认区联社审批贷款成功";
                    } else {
                        loanApp.setProcessStat(LoanStat.APPROVAL_FAIL_LIANSHE.getValue());
                        remark = "已确认区联社贷款审批未通过";
                    }

                } else {
                    throw new ServiceException("只有“贷款审查分配人”可以记录区联社审批贷款的结果");
                }
            }

            loanApp.setCurProcessUpdateTime(DateUtil.getCurrentTime("yyyy-MM-dd"));
            loanApp.setCurProcessHandler(loginUser.getUserName());
            LoanApplication loanAppRet = loanApplicationDao.save(loanApp);

            saveJournal(loanApp, loginUser.getUserName(), remark);


            // ************开始记录通知消息**************/
            //生成审批通知消息
            MsgInfo msgInfo = new MsgInfo();
            msgInfo.setLoanId(loanApp.getLoanId());

            if (approvalResult) {
                msgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请" + loanApp.getLoanId() + "审批成功");
            } else {
                msgInfo.setMsg(loanApp.getBorrowerName() + "的贷款申请"  + loanApp.getLoanId() + "审批失败");
            }

            msgInfo.setMsgTime(DateUtil.getCurrentTime("yyyyMMdd"));
            msgInfo.setUserName(loanApp.getOperator());

            msgInfoDao.save(msgInfo);

            //TODO 新增修改为update
            List<LoanDetailedReport> reports = loanDetailedReportDao.findAllByLoanId(id);
            if (reports != null && reports.size() == 1) {
                LoanDetailedReport loanDetailedReport = reports.get(0);
                loanDetailedReportDao.save(loanApp2Report(loanAppRet, loanDetailedReport));
            } else {
                throw new ServiceException("报表流水出现脏数据");
            }
        }


    }


    private LoanApplication vo2po(LoanBean loanBean) {
        LoanApplication loanApplication = new LoanApplication();
        BeanUtils.copyProperties(loanBean, loanApplication);
        return loanApplication;
    }

    private LoanBean po2vo(LoanApplication loanApplication) {
        LoanBean loanBean = new LoanBean();
        BeanUtils.copyProperties(loanApplication, loanBean);
        return loanBean;
    }

    /**
     * 保存RoadMap流水信息
     *
     * @param loanApplication loanApplication
     * @param userId          userId
     * @param remark          remark
     */
    private void saveJournal(LoanApplication loanApplication, String userId, String remark) {
        //记录流水信息
        LoanJournal journal = new LoanJournal();
        journal.setLoanId(loanApplication.getLoanId());
        journal.setCurProcessHandler(loanApplication.getCurProcessHandler());
        //记录年份，方便页面显示
        String yearStr = DateUtil.getCurrentTime("yyyy");
        journal.setCurProcessUpdateYear(yearStr);

        //记录日期，方便页面显示
        String dateStr = DateUtil.getCurrentTime("MM-dd");
        journal.setCurProcessUpdateDate(dateStr);

        journal.setOrgId(loanApplication.getOrgId());
        journal.setProcessStat(loanApplication.getProcessStat());

        //记录流水描述
        String nowTime = DateUtil.getCurrentTime("HH点mm分");

        String userInfo = findUserInfo4Journal(userId);
        remark = nowTime + "&nbsp;&nbsp;&nbsp;&nbsp;" + userInfo + remark;
        journal.setRemark(remark);

        loanJournalDao.save(journal);
    }

    /**
     * 根据登陆用户ID获取其角色及真名字
     *
     * @param loginUserID loginUserID
     * @return String String
     */
    private String findUserInfo4Journal(String loginUserID) {
        UserInfo loginUser = userInfoDao.findOne(loginUserID);
        List<RoleInfo> roleInfos = userRoleDao.findRoleInfoByUserName(loginUserID);

        String result = loginUser.getRealName() + "（工号：" + loginUserID + "；角色：";

        for (int i = 0; i < roleInfos.size(); i++) {
            RoleInfo roleInfo = roleInfos.get(i);

            result += roleInfo.getRoleName();

            if (i < roleInfos.size() - 1) {
                result += ",";
            }
        }

        result += "）";

        return result;
    }


    /**
     * 更新贷款报表流水记录
     *
     * @param loanApplication    loanApplication
     * @param loanDetailedReport loanDetailedReport
     * @return LoanDetailedReport LoanDetailedReport
     */
    private LoanDetailedReport loanApp2Report(LoanApplication loanApplication, LoanDetailedReport loanDetailedReport) {
        String detail = loanApplication.getDetail();

        loanDetailedReport.setLoanId(loanApplication.getLoanId());
        loanDetailedReport.setPickupTime(loanApplication.getPickupTime());
        if (loanApplication.getProcessStat() != null) {
            loanDetailedReport.setProcessStat(loanApplication.getProcessStat());
            loanDetailedReport.setLoanResult(LoanStat.Helper.findCnValue(loanApplication.getProcessStat()));
            if(loanApplication.getProcessStat().equals("EXAMINE_SUCC_LIANSHE")||
                    loanApplication.getProcessStat().equals("EXAMINE_SUCC_GEJING")||
                    loanApplication.getProcessStat().equals("EXAMINE_FAIL")||
                    loanApplication.getProcessStat().equals("CAN_NOT_EXAMINE")){
                loanDetailedReport.setApprovalTime(loanApplication.getCurProcessUpdateTime());
            }
        }
        loanDetailedReport.setExamineHandler(loanApplication.getApprovalHandler());

        ObjectMapper mapper = new ObjectMapper();
        try {
            LoanInfo loanInfo = mapper.readValue(detail, LoanInfo.class);
            //借款人姓名
            loanDetailedReport.setBorrowerName(loanInfo.getBorrowerName());
            //借款人身份证号
            loanDetailedReport.setCredentialNo(loanInfo.getCredentialNo());
            //营销人
            loanDetailedReport.setMarketer(loanInfo.getMarketer());
            //经办人
            loanDetailedReport.setOperator(loanInfo.getOperator());
            //转换岗位
            int marketerPost = Integer.parseInt(loanInfo.getMarketerPost());
            loanDetailedReport.setMarketerPost(BaseConst.POSTS[marketerPost]);
            int operatorPost = Integer.parseInt(loanInfo.getOperatorPost());
            loanDetailedReport.setOperatorPost(BaseConst.POSTS[operatorPost]);
            //转换交易类型
            int businessType = Integer.parseInt(loanInfo.getBusinessTypes());
            loanDetailedReport.setBusinessType(BaseConst.BUSINESSTYPES[businessType]);
            //审批贷款类型
            loanDetailedReport.setApprBusinessType(BaseConst.BUSINESSTYPES[businessType]);

            //贷款金额
            loanDetailedReport.setAmount(loanInfo.getAmount());
            //贷款期限
            loanDetailedReport.setTerm(loanInfo.getTerm());
            //转换担保方式
            int guaranteeMethod = Integer.parseInt(loanInfo.getGuaranteeMethod());
            loanDetailedReport.setGuaranteeMethod(BaseConst.GUARANTEEMETHODS[guaranteeMethod]);

            //审批担保方式
            if (loanInfo.getExamineGuaranteeMethod() != null) {
                int examineGuaranteeMethod = Integer.parseInt(loanInfo.getExamineGuaranteeMethod());
                loanDetailedReport.setApprGuaranteeMethod2(BaseConst.GUARANTEEMETHODS[examineGuaranteeMethod]);
            }
            //审批金额
            loanDetailedReport.setApprAmount(loanInfo.getExamineAmount());
            //审批期限
            loanDetailedReport.setApprTerm(loanInfo.getExamineTerm());
            //审批利率
            loanDetailedReport.setApprRate(loanInfo.getExamineRate());
            //转换还款方式
            int repaymentMethod = Integer.parseInt(loanInfo.getRepaymentMethod());
            loanDetailedReport.setRepaymentMethod(BaseConst.REPAYMENTMETHODS[repaymentMethod]);
            //转换续贷标志
            int isRenew = Integer.parseInt(loanInfo.getIsRenew());
            loanDetailedReport.setIsRenew(BaseConst.ISREVIEWS[isRenew]);

            //remark的合并操作
            String ysfRemark1 = loanInfo.getYsfRemark1();
            String yszfRemark2 = loanInfo.getYszfRemark2();
            String syfRemark2 = loanInfo.getSyfRemark2();
            String esfRemark = loanInfo.getEsfRemark();
            String xfdkRemark = loanInfo.getXfdkRemark();
            String jydkRemark1 = loanInfo.getJydkRemark1();
            String syryRemark2 = loanInfo.getSyryRemark2();
            String dmfbRemark2 = loanInfo.getDmfbRemark2();

            StringBuilder sb = new StringBuilder();
            if (ysfRemark1 != null) {
                sb.append(BaseConst.YSFREMARK1[Integer.parseInt(ysfRemark1)]);
                sb.append("；");
            }
            if (yszfRemark2 != null) {
                sb.append(yszfRemark2);
                sb.append("；");
            }
            if (syfRemark2 != null) {
                sb.append(BaseConst.SYFREMARK2[Integer.parseInt(syfRemark2)]);
                sb.append("；");
            }
            if (esfRemark != null) {
                sb.append(BaseConst.ESFREMARK[Integer.parseInt(esfRemark)]);
                sb.append("；");
            }
            if (xfdkRemark != null) {
                sb.append(BaseConst.XFDKREMARK[Integer.parseInt(xfdkRemark)]);
                sb.append("；");
            }
            if (jydkRemark1 != null) {
                sb.append(BaseConst.JYDKREMARK1[Integer.parseInt(jydkRemark1)]);
                sb.append("；");
            }
            if (syryRemark2 != null) {
                sb.append(syryRemark2);
                sb.append("；");
            }
            if (dmfbRemark2 != null) {
                sb.append(dmfbRemark2);
                sb.append("；");
            }
            loanDetailedReport.setRemark(sb.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return loanDetailedReport;
    }

    /**
     * 转换贷款上报报表entity
     * @param loanApplication loanApplication
     * @return LoanSubmitReport
     */
    private LoanSubmitReport loanApp2SubmitReport(LoanApplication loanApplication) {
        String detail = loanApplication.getDetail();
        LoanSubmitReport loanSubmitReport = new LoanSubmitReport();
        loanSubmitReport.setLoanId(loanApplication.getLoanId());
        loanSubmitReport.setInitTime(DateUtil.getCurrentTime("yyyy-MM-dd"));
        loanSubmitReport.setPickupTime(loanApplication.getPickupTime());
        loanSubmitReport.setPrintFlag("未打印");

        ObjectMapper mapper = new ObjectMapper();
        try {
            LoanInfo loanInfo = mapper.readValue(detail, LoanInfo.class);
            //转换交易类型
            int businessType = Integer.parseInt(loanInfo.getBusinessTypes());
            loanSubmitReport.setBusinessType(BaseConst.BUSINESSTYPES[businessType]);
            loanSubmitReport.setBorrowerName(loanInfo.getBorrowerName());
            loanSubmitReport.setCredentialNo(loanInfo.getCredentialNo());
            loanSubmitReport.setAmount(loanInfo.getAmount());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return loanSubmitReport;
    }

    /**
     * 转换贷款审查报表entity
     * @param loanApplication
     * @return
     */
    private LoanAssignReport loanApp2AssignReport(LoanApplication loanApplication){
        String detail = loanApplication.getDetail();
        LoanAssignReport loanAssignReport = new LoanAssignReport();
        loanAssignReport.setLoanId(loanApplication.getLoanId());
        loanAssignReport.setInitTime(DateUtil.getCurrentTime("yyyy-MM-dd"));
        loanAssignReport.setPickupTime(loanApplication.getPickupTime());
        loanAssignReport.setApprovalTime(loanApplication.getCurProcessUpdateTime());
        loanAssignReport.setExamineHandler(loanApplication.getApprovalHandler());
        loanAssignReport.setLoanResult(LoanStat.Helper.findCnValue(loanApplication.getProcessStat()));
        loanAssignReport.setPrintFlag("未打印");

        ObjectMapper mapper = new ObjectMapper();
        try {
            LoanInfo loanInfo = mapper.readValue(detail, LoanInfo.class);
            //转换交易类型
            int businessType = Integer.parseInt(loanInfo.getBusinessTypes());
            loanAssignReport.setBusinessType(BaseConst.BUSINESSTYPES[businessType]);
            loanAssignReport.setBorrowerName(loanInfo.getBorrowerName());
            loanAssignReport.setCredentialNo(loanInfo.getCredentialNo());
            loanAssignReport.setAmount(loanInfo.getAmount());

            loanAssignReport.setApprAmount(loanInfo.getExamineAmount());
            loanAssignReport.setApprTerm(loanInfo.getExamineTerm());
            loanAssignReport.setApprRate(loanInfo.getExamineRate());

            //审批担保方式
            if (loanInfo.getExamineGuaranteeMethod() != null) {
                int examineGuaranteeMethod = Integer.parseInt(loanInfo.getExamineGuaranteeMethod());
                loanAssignReport.setApprGuaranteeMethod2(BaseConst.GUARANTEEMETHODS[examineGuaranteeMethod]);
            }

            //审批还款方式
            int repaymentMethod = Integer.parseInt(loanInfo.getExamineRepaymentMethod());
            loanAssignReport.setApprRepaymentMethod(BaseConst.REPAYMENTMETHODS[repaymentMethod]);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return loanAssignReport;
    }
}